package com.example.service.impl;

import com.example.client.BaseClient;
import com.example.vo.User;
import com.example.common.Rt;
import com.example.service.UserServiceApi;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * @Author zhangming
 * @Date 2021/10/8 17:05
 * @Version 1.0
 * @Desc: TODO
 */
@Slf4j
@DefaultProperties(defaultFallback = "fallbackMethod")
@Service
public class UserServiceApiImpl implements UserServiceApi {

	@Autowired
	private BaseClient baseClient;

	@Autowired
	private DiscoveryClient discoveryClient;

	@Autowired
	private RestTemplate restTemplate;

	@Override
	public Rt<User> getByFeign(Integer id) {
		return baseClient.getById(id);
	}

	//单个方法熔断
	//@HystrixCommand(fallbackMethod = "fallbackMethod")
	@HystrixCommand
	@Override
	public Rt<User> getByRestTemplate(Integer id) {
		//服务发现实例验证
		List<ServiceInstance> serviceInstanceList = discoveryClient.getInstances("user-service");
		ServiceInstance instance = serviceInstanceList.get(0);
		String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/user/" + id;

		//熔断器三个状态模拟测试
		if(1 == id){
			log.error("熔断器三个状态模拟测试...");
			throw new RuntimeException("熔断器三个状态模拟测试...");
		}

		//负载均衡RestHttp请求
		String serviceUrl = "http://user-service/user/" + id;
		return restTemplate.getForObject(serviceUrl, Rt.class);
	}

	/**
	 * Hystrix Rollback Method
	 * 1.局部（要和被熔断方法 返回值和参数列表一致）
	 * 2.全局（返回值类型和被熔断方法一致，参数列表必须为空）
	 */
	public Rt<User> fallbackMethod() {
		log.error("服务器正忙，请稍后重试...");
		return Rt.fail("服务器正忙，请稍后重试...");
	}

}
